package ru.susu.algebra.matrix;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import ru.susu.algebra.operation.IOperation;

/**
 * Операция получения номеров уникальных по модулю {@link BigIntMatrixModUniqueRowsExtractor#_mod} строк матрицы.
 * В результате будут минимальные номера строк, раньше которых еще не попадалось раных им.
 *
 * @author akargapolov
 * @since: 03.05.2010
 */
public class BigIntMatrixModUniqueRowsExtractor implements IOperation<Integer[]>
{
	private BigInteger _mod;

	public BigIntMatrixModUniqueRowsExtractor(BigInteger mod)
	{
		_mod = mod;
	}

	/**
	 * Возвращает массив номеров уникальных по модулю {@link #_mod} строк.
	 * @param sources - sources[0] исходная матрица {@link Matrix}
	 * @return номера уникальных строк
	 */
	@Override
	public Integer[] performOperation(Object... sources)
	{
		System.out.println("Matrix mod " + _mod + ":");
		Matrix matrix = (Matrix)sources[0];
		Matrix modMatrix = new BigIntMatrixModTransformer(_mod).transformObject(matrix);
		List<Integer> result = new ArrayList<Integer>();
		for (int row = 0;row < modMatrix.getRows(); row++)
		{
			int rowIndex = getEqualsBeforeRow(modMatrix, row);
			String suffix = "";
			if (rowIndex == -1)
			{
				result.add(row);
			}
			else
			{
				suffix = " - equals " + rowIndex;
			}
			System.out.println(Arrays.toString(modMatrix.getArrayRow(row)) + suffix);
		}
		return result.toArray(new Integer[result.size()]);
	}

	/**
	 * Возвращает индекс строки до проверяемой, которая полностью совпадает с проверяемой
	 * @param modMatrix матрица, элементы которой вычислены по модулю {@link #_mod}
	 * @param row проверяемая строка
	 * @return индекс эквивалентной строки либо -1, если строка уникальна
	 */
	protected int getEqualsBeforeRow(Matrix modMatrix, int row)
	{
		for (int row1 = 0;row1 < row; row1++)
			if (Arrays.equals(modMatrix.getArrayRow(row1), modMatrix.getArrayRow(row)))
			{
				return row1;
			}
		return -1;
	}
}
